package com.louis.xml_aop.impl;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author XRY
 * @date 2023年06月27日14:06
 */

//切面类
@Component //表示在spring的ioc容器中进行管理
public class LogAspect {
    //前置通知
    public void beforeMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("前置通知,增强的方法名称" + name + " , 参数" + Arrays.toString(args));
    }
    // 返回通知
    public void afterReturningMethod(JoinPoint joinPoint, Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("返回通知, 增强方法名称" + name + " , 返回结果" + result);
    }
    // 异常通知
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable Exception){
        String name = joinPoint.getSignature().getName();
        System.out.println("异常通知, 增强方法名称" + name + " , 返回结果" + Exception);
    }

    // 后置通知
    public void afterMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知, 增强方法名称" + name);
    }
    // 环绕通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String argsString = Arrays.toString(args);
        Object result = null;
        try {
            System.out.println("环绕通知, 目标方法之前执行");
            //调用目标方法
             result = joinPoint.proceed();

            System.out.println("环绕通知, 目标方法返回值之后执行");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("环绕通知, 目标方法出现异常执行");
        } finally {
            System.out.println("环绕通知, 目标方法执行完毕");
        }
        return result;
    }


    //重用切入点表达式,定义一个方法，之后在需要切入点的时候直接调用这个方法
    /*
    * 在同一个类下，可以直接使用:@Before("pointcut()")
    * 在不同的类中，需要加入类的路径:  @Before("com.louis.annotation_aop.impl.LogAspect.pointcut()")
    * */
    @Pointcut(value = "execution(public int com.louis.xml_aop.impl.CalculatorImpl.*(..))")
    public void pointcut(){

    }
}
